﻿using System;
using System.Reflection;
using Moki;
using Moki.State;

namespace Moki.Core
{
    /// <summary>
    /// Adds stub. Gets stubs list from mock interceptor. Changes state to stubbing.
    /// </summary>
    internal class StubPerformer
    {
        private MockRepository _mockRepository;
        private StateChangedNotifier _notifier = new StateChangedNotifier();

        public StubPerformer(MockRepository mockRepository, StateController stateController)
        {
            _mockRepository = mockRepository; 
            stateController.RegisterNotifier(_notifier);
        }

        public void BeginStubbing()
        {
            _notifier.NotifyStateChanged(MockingState.Stubbing);
        }

        public void EndStubbing()
        {
            _notifier.NotifyStateChanged(MockingState.Acting);
        }

        public void AddStub(object proxy, StubContext stub)
        {
            if (proxy == null)
                throw new ArgumentNullException("Proxy object is null.");
            else
                _mockRepository.GetInterceptor(proxy).AddStub(stub);
        }

        public StubContext GetStub(object proxy, MethodInfo method, Arguments arguments)
        {
            return _mockRepository.GetInterceptor(proxy).Stubs.Find(s => s.Method.Name == method.Name && s.Arguments.EqualsValues(arguments));
        }

        public StubContext GetStub(object proxy, MethodInfo method)
        {
            return _mockRepository.GetInterceptor(proxy).Stubs.Find(s => s.Method.Name == method.Name);
        }
    }
}
